-
Notifications
You must be signed in to change notification settings - Fork 1.9k
chore(trie): Use trie changesets for engine unwinding #18878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(trie): Use trie changesets for engine unwinding #18878
Conversation
bdaeb41
to
70d24d4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that this makes things simpler, I have a question and suggestion for a helper method but otherwise this looks good to me
let trie_revert = self.trie_reverts(range.clone())?; | ||
self.write_trie_updates_sorted(&trie_revert)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, i like that this is now just a call to a provider fn
// Sanity check that we have static files available to unwind to the target block. | ||
let highest_static_file_block = | ||
provider_factory.static_file_provider().get_highest_static_files().max_block_num(); | ||
if highest_static_file_block | ||
.filter(|highest_static_file_block| *highest_static_file_block > target) | ||
.is_none() | ||
{ | ||
return Err(eyre::eyre!("static files not available for target block {target}, highest is {highest_static_file_block:?}")); | ||
} | ||
|
||
// Move all applicable data from database to static files. | ||
pipeline.move_to_static_files()?; | ||
if self.offline { | ||
info!(target: "reth::cli", "Performing an unwind for offline-only data!"); | ||
} | ||
|
||
pipeline.unwind(target, None)?; | ||
if let Some(highest_static_file_block) = highest_static_file_block { | ||
info!(target: "reth::cli", ?target, ?highest_static_file_block, "Executing a pipeline unwind."); | ||
} else { | ||
info!(target: "reth::cli", ?target, "Executing a database unwind."); | ||
let provider = provider_factory.provider_rw()?; | ||
info!(target: "reth::cli", ?target, "Executing a pipeline unwind."); | ||
} | ||
info!(target: "reth::cli", prune_config=?config.prune, "Using prune settings"); | ||
|
||
provider | ||
.remove_block_and_execution_above(target) | ||
.map_err(|err| eyre::eyre!("Transaction error on unwind: {err}"))?; | ||
// This will build an offline-only pipeline if the `offline` flag is enabled | ||
let mut pipeline = | ||
self.build_pipeline(config, provider_factory, components.evm_config().clone())?; | ||
|
||
// update finalized block if needed | ||
let last_saved_finalized_block_number = provider.last_finalized_block_number()?; | ||
if last_saved_finalized_block_number.is_none_or(|f| f > target) { | ||
provider.save_finalized_block_number(target)?; | ||
} | ||
// Move all applicable data from database to static files. | ||
pipeline.move_to_static_files()?; | ||
|
||
provider.commit()?; | ||
} | ||
pipeline.unwind(target, None)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the reasoning behind this, that currently we pretty much always have static files and will now always be doing a pipeline unwind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, with the work @shekhirin has been doing we always have static files, there's never a situation where static files are behind mdbx because we don't even write that data to mdbx anymore. So if static files don't have the data we can't do anything, just error out, otherwise always pipeline.
} | ||
|
||
#[test] | ||
fn test_write_trie_updates_sorted() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea this test is helpful to understand this pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, appreciate the cleanup in reth stage unwind
Closes #18517
This PR primarily targets the
unwind_trie_state_range
provider method, which is used by the engine API to unwind the db during reorgs.This method was previously also potentially used by the unwind pipeline stage, but only in an
else
block which should never get hit anymore. This else block was replaced with an error.unwind_trie_state_range
was previously recomputing trie updates using a StateRoot calculation, but it is now able to skip that step and simply read trie updates from the trie changeset tables instead. To make applying these updates easier thewrite_trie_updates
method is superceded bywrite_trie_updates_sorted
.